package com.computaris.servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.computaris.entities.SubscriberDetails;
import com.computaris.ws.Event;
import com.computaris.ws.EventImpl;
import com.computaris.ws.PostpayBillingWsImpl;
import com.sun.istack.logging.Logger;

public class UploadData extends HttpServlet {
	private static final long serialVersionUID = 7548919575234739743L;
	
	Logger log = Logger.getLogger(UploadData.class);

	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
		res.setContentType("text/html");
//		WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
//		eventDao = (EventDao)springContext.getBean("eventDao");
		EventImpl impl = new EventImpl();
		PostpayBillingWsImpl pimpl = new PostpayBillingWsImpl();

		try {
			@SuppressWarnings("unchecked")
			List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(req);
			for(FileItem item : items) {
				BufferedReader br = new BufferedReader(new InputStreamReader(item.getInputStream()));
				String str = null;
				int nrEntries = 0;
				while((str = br.readLine()) != null) {
					log.info("checking line " + str);
					nrEntries++;
					if(nrEntries > 20) {
						res.getWriter().write("Too many entries in file");
						br.close();
						return;
					}
					String[] ss = str.split("\\|");
					if(ss.length != 7) {
						res.getWriter().write("Invalid number of arguments on line " + str + "<br/>");
						br.close();
						return;
					}
					// call type check
					if(!"0".equals(ss[2]) && !"1".equals(ss[2]) && !"2".equals(ss[2]) && !"3".equals(ss[2])) {
						res.getWriter().write("Bad call type " + str + " - " + ss[2]);
						br.close();
						return;
					}
					int callType = Integer.parseInt(ss[2]);
					// call duration check
					if(callType == 1) {
						
					} else {
						if((ss[3].length() == 0 && callType == 0) || (ss[3].length() > 0 && callType != 0)) {
							res.getWriter().write("Bad call type/call duration combination " + str + " - " + ss[2] + " - " + ss[3]);
							br.close();
							return;
						}
					}
					if(callType == 0) {
						try {
							Integer.parseInt(ss[3]);
						} catch (Exception ex) {
							res.getWriter().write("call duration must be integer " + str + " - " + ss[3]);
							br.close();
							return;
						}
					}
					// event date check
					if(!"0".equals(ss[2]) && !"1".equals(ss[2]) && !"2".equals(ss[2]) && !"3".equals(ss[2])) {
						res.getWriter().write("Bad call type " + str + " - " + ss[2]);
						br.close();
						return;
					}
					
					try {
						Long.parseLong(ss[0]);
					} catch (Exception e) {
						res.getWriter().write("Bad msisdn " + str + " - " + ss[0]);
						br.close();
						return;
					}
				}
				br.close();
			}
			for(FileItem item : items) {
				BufferedReader br = new BufferedReader(new InputStreamReader(item.getInputStream()));
				String str = null;
				int nrEntries = 0;
				while((str = br.readLine()) != null) {
					nrEntries++;
					if(nrEntries > 15) {
						continue;
					}
					String[] ss = str.split("\\|");
					long msisdn = 0;
					try {
						msisdn = Long.parseLong(ss[0]);
					} catch (Exception e) {
						res.getWriter().write("Bad msisdn " + str + " - " + ss[0]);
						br.close();
						return;
					}
					
					SubscriberDetails details = pimpl.getSubscriberDetails("" + msisdn);
					if(details == null || details.getId() == null) {
						res.getWriter().write("msisdn not found or is suspended: " + str + " - " + ss[0]);
						br.close();
						return;
					}
					
					Event event = new Event();
					int callType = Integer.parseInt(ss[2]);
					if(callType == 0) {
						event.setAmount(Integer.parseInt(ss[3]));
						event.setUom(1);
					} else if(callType == 1 || callType == 2) {
						event.setAmount(Integer.parseInt(ss[5]));
						event.setUom(2);
					} else {
						event.setAmount(Integer.parseInt(ss[4]));
						event.setUom(1);
					}
					event.setCharge(Integer.parseInt(ss[6]));
					event.setType(callType);
					event.setSubsriberId(Long.parseLong(ss[0]));
					DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
					Date dt = formatter.parse(ss[1]);
					event.setEventDate(dt);
					event.setId(1);
					
					log.info("saving in DB line " + str + " obj = " + event.toString());
					
					Exception ex = impl.createEvent(event);
					if(ex != null) {
						res.getWriter().write("Exception adding to database: " + ex.toString());
						br.close();
						return;
					}
				}
				br.close();
				res.getWriter().write("Successfuly uploaded " + nrEntries + " records and stored in DB");
			}
		} catch (Exception e) {
			for(StackTraceElement st : e.getStackTrace()) {
				res.getWriter().write(st.toString() + "<br/>");
			}
		}
		
		res.flushBuffer();
	}
}
